Momento TopicsでWebSocketを実現するサンプルを試してみた
はじめに
今回はMomentoの中のサービスの1つである、Momento TopicsをWebSocketとして使ってみます。先日開催されたServerless Days 2024に参加して、Momentoの話を聞いて調べたところ、以下の記事を見つけました。何と、以下の数行でWebSocketが実現できると書かれています。まじかよ!
// Subscribe
await topicClient.subscribe('websocket', 'mychannel', {
onItem: (data) => { handleItem(data.valueString()); },
onError: (err) => { console.error(err); }
});
// Publish
await topicClient.publish('websocket', 'mychannel', JSON.stringify({ detail }));
Momento公式SDKの中にサンプルがあったので、動作確認しながらMomento Topicsを試してみます。
ソース元
以下にMomentoのJavaScript用のSDKが公開されており、こちらのコードの一部を試しに使っていきます。SDKの実装自体はTypeScriptで書かれています。
関連箇所
- https://github.com/momentohq/client-sdk-javascript/tree/main/examples/nodejs/token-vending-machine
- https://github.com/momentohq/client-sdk-javascript/tree/main/examples/web/vite-chat-app
全体の構成としては、MomentoのAPIキーから一時的な認証情報(ここからは公式サイトを真似てMomento Tokenと呼びます)を生成するためのトークン生成器と実際に生成したMomento Tokenを使用するサンプルWebアプリ(Vite)に分かれています。
使ってみた
早速サンプルを試してみます。まずはViteをベースにしたサンプルのReadmeを読むとトークン生成器の準備が必要と書かれています。なので、先にトークン生成器でMomento Tokenを生成できるよう準備します。
token-vending-machineの作成
上記のリソースをAWS環境にデプロイするため、事前にMomentoのコンソールにログインしAPIキーを生成します。生成する流れは以下の資料のp.69~p.76辺りをみると確認できます。
手順にはないですが、サンプルが特定のCacheを使うことが前提となっているので、このまま実行すると権限不足になります。なので、以下のコードを変更し生成するMomento Tokenの権限を広げます。(本番では使用するCacheのみに設定したほうがよいです)
DisposableTokenScope
を以下のように変更します。
export const tokenPermissions: DisposableTokenScope = {
permissions: [
{
role: CacheRole.ReadWrite,
cache: AllCaches, //←元ソース cache: 'default-cache',
},
{
role: TopicRole.PublishSubscribe,
cache: AllCaches, //←元ソース cache: 'default-cache',
topic: AllTopics,
},
],
};
Readmeに従って、MomentoApiKeyパラメータに取得したMomento APIキーをセッティングしてCDKからリソースをデプロイします。一点注意として、Docker上でのビルドが実行されるのでDocker DesktopやRancher Desktopなどを事前に起動してください。
git clone https://github.com/momentohq/client-sdk-javascript.git
cd examples/nodejs/token-vending-machine/infrastructure
npm install
npm run deploy -- --parameters MomentoApiKey=<YOUR_MOMENTO_API_KEY>
デプロイすると以下のようなAWSリソースが展開されます。ターミナルやブラウザなどからAPI GatewayのエンドポイントにアクセスするとMomento Tokenが取得できます。
curlでMomento Tokenが取得できるか確認できます。
% curl https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/prod/
{"authToken":"eyJXXXXXXXXXXXX","expiresAt":1727518127}%
デフォルトだとOpen設定で誰でもトークン取得可能ですが、Configを切り替えることでLambdaAuthorizerやAmazonCognitoを使う方式にも切り替えられます。詳細は以下の部分を確認してください。
サンプルアプリの実行(Vite)
ここから使用するMomento Topicの作成と、サンプルアプリのデプロイを実施します。まずはMomento Cacheの作成です。Momento Consoleから以下のように画面に沿ってCacheを作成します。
作成できたら次はサンプルアプリを実行します。
実行は非常に単純で、Config用のファイルがあるので先ほどデプロイしたAPI Gatewayのエンドポイントを設定し、使用するMomento Cacheの名前を設定しローカルで実行することで使用できます。VITE_TOKEN_VENDING_MACHINE_AUTH_TYPE
はトークン生成器に合わせてlambda
,cognito
も設定出来ます。
VITE_TOKEN_VENDING_MACHINE_URL="<デプロイしたAPI GatewayのURL>"
VITE_MOMENTO_CACHE_NAME="<momentoに設定したcacheの名前>"
VITE_TOKEN_VENDING_MACHINE_AUTH_TYPE="open"
上記が設定できたら以下でローカル実行できます。
cd -
cd examples/web/vite-chat-app
npm install
npm run dev
上記デプロイができるとhttp://localhost:5173
でアプリに接続できます。アプリを2つ開くと以下のように、Momento Topicを経由してWebSocketが実現出来ることが分かります。左側がtest1ユーザで、右側がtest2ユーザです。
ただ、なぜか重複してデータが表示されるので描画の際は冪等な処理が必要そうです。
サンプルコードを見ると、SDK経由でpublish/subscribeするだけでWebSocketが実現できています。今後以下のコード部分をベースに、別途IoTに関連するサンプルを作って詳細を確認してみます。
所感
他にもWebSocketのサービスはありそうですが、バックエンドの実装をほぼMomento Topics側にお願いできるのでかなり有用に感じました!気になる方はぜひ一緒にサンプル試してみてください!
参考